package tron.oauth.config;

import com.alibaba.fastjson.JSONObject;
import lombok.SneakyThrows;
import org.springframework.http.MediaType;
import org.springframework.security.authentication.*;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import javax.servlet.FilterChain;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

/**
 * 用户密码登录验证
 */
public class CustomerLoginFilter extends UsernamePasswordAuthenticationFilter {

    private final AuthenticationManager authenticationManager;


    public CustomerLoginFilter(AuthenticationManager authenticationManager) {
        this.authenticationManager = authenticationManager;
    }


    /**
     * 登录数据处理
     * 前端这里获取到的用户密码应该是未加密的，如果前端加密应该在这里解密
     */
    @SneakyThrows
    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
        final JSONObject userJson = JSONObject.parseObject(request.getInputStream(), JSONObject.class);
        System.out.println("-------获取登录请求参数------" + userJson);
        // 前端这里获取到的用户密码应该是未加密的，如果前端加密应该在这里解密
        return authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(userJson.getString("username"), userJson.getString("password")));
    }

    /**
     * 登录成功封装用户权限等信息
     */
    @Override
    protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) {
        System.out.println("---------登录成功----------");

        // 记录登录日志
        try {
            //登录成功时，返回json格式进行提示
            response.setContentType(MediaType.APPLICATION_JSON_VALUE);
            response.setCharacterEncoding(StandardCharsets.UTF_8.name());
            response.setStatus(HttpServletResponse.SC_OK);
            PrintWriter out = response.getWriter();
            Map<String, Object> map = new HashMap<String, Object>(4);
            map.put("code", HttpServletResponse.SC_OK);
            map.put("message", "登陆成功！");
            out.write(JSONObject.toJSONString(map));
            out.flush();
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, AuthenticationException failed)  {
        System.out.println("--------------登录失败-----------");
        try {
            response.setContentType(MediaType.APPLICATION_JSON_VALUE);
            response.setCharacterEncoding(StandardCharsets.UTF_8.name());
            PrintWriter out = response.getWriter();
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            Map<String, Object> map = new HashMap<>();
            map.put("status", HttpServletResponse.SC_UNAUTHORIZED);
            if (failed instanceof LockedException) {
                map.put("msg", "账户被锁定，登陆失败！");
            } else if (failed instanceof BadCredentialsException) {
                map.put("msg", "账户名或密码输入错误，登陆失败！");
            } else if (failed instanceof DisabledException) {
                map.put("msg", "账户被禁用，登陆失败！");
            } else if (failed instanceof AccountExpiredException) {
                map.put("msg", "账户已过期，登陆失败！");
            } else if (failed instanceof CredentialsExpiredException) {
                map.put("msg", "密码已过期，登陆失败！");
            } else {
                map.put("msg", "登陆失败！");
            }
            out.write(JSONObject.toJSONString(map));
            out.flush();
            out.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
